package com.bdq.content.application.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.bdq.common.entity.UserContext;
import com.bdq.common.entity.common.PageResult;
import com.bdq.common.enums.YesOrNoEnum;
import com.bdq.common.feign.interaction.param.InteractionDataGetParam;
import com.bdq.common.feign.interaction.vo.InteractionDataGetVO;
import com.bdq.common.feign.interaction.vo.InteractionDataListVO;
import com.bdq.common.feign.user.param.UserGetParam;
import com.bdq.common.feign.user.vo.UserFollowVO;
import com.bdq.common.feign.user.vo.UserGetVO;
import com.bdq.common.feign.user.vo.UserListVO;
import com.bdq.common.utils.UserContextUtil;
import com.bdq.content.application.model.dto.ContentDetailAppDTO;
import com.bdq.content.application.model.dto.ContentListAppDTO;
import com.bdq.content.application.model.query.ContentDetailQry;
import com.bdq.content.application.model.query.ContentQueryQry;
import com.bdq.content.application.model.query.ContentSearchQry;
import com.bdq.content.application.model.query.UserPostPageQry;
import com.bdq.content.application.service.ContentQueryService;
import com.bdq.content.application.service.MyFeignClient;
import com.bdq.content.domain.model.agg.ContentAgg;
import com.bdq.content.domain.model.dto.ContentDetailDomainDTO;
import com.bdq.content.domain.model.dto.ContentListDomainDTO;
import com.bdq.content.domain.model.dto.req.ContentDetailReqDTO;
import com.bdq.content.domain.model.dto.req.ContentListInteractionReqDTO;
import com.bdq.content.domain.model.dto.req.ContentListReqDTO;
import com.bdq.content.domain.model.dto.req.ContentListUserReqDTO;
import com.bdq.content.domain.service.ContentDomainService;
import com.bdq.common.config.common.TokenInterceptor;
import com.bdq.content.infrastructure.model.dto.ContentQueryInfraDTO;
import com.bdq.content.infrastructure.persistence.mysql.pojo.Content;
import com.bdq.content.infrastructure.persistence.mysql.service.ContentService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author malei
 * @date 2024-05-10 16:21
 */
@Service
public class ContentQueryServiceImpl implements ContentQueryService {

    @Resource
    private ContentDomainService contentDomainService;

    @Resource
    private ContentService contentService;

    @Resource
    private MyFeignClient myFeignClient;

    @Override
    public ContentDetailAppDTO detail(ContentDetailQry qry) {
        // 1 获取用户信息
        UserContext userContext = UserContextUtil.getLoginUserContext(TokenInterceptor.getToken());
        if (Objects.isNull(userContext)) {
            userContext = UserContext.defaultContext();
        }

        // 2 获取交互数据
        InteractionDataGetParam interactionDataGetParam = new InteractionDataGetParam();
        interactionDataGetParam.setContentId(qry.getContentId());
        interactionDataGetParam.setUserId(userContext.getId());
        InteractionDataGetVO interactionDataGetVO = myFeignClient.getData(interactionDataGetParam);

        // 3 聚合对象
        ContentAgg contentAgg = new ContentAgg();
        contentDomainService.contentAggFill(qry.getContentId(), contentAgg);

        // 4 作者信息
        UserGetParam userGetParam = new UserGetParam();
        userGetParam.setUserId(contentAgg.getUserId());
        UserGetVO userGetVO = myFeignClient.getUser(userGetParam);

        // 5 获取内容详情
        ContentDetailReqDTO reqDTO = Convert.convert(ContentDetailReqDTO.class, interactionDataGetVO);
        reqDTO.setContentId(qry.getContentId());
        reqDTO.setCurrentUserId(userContext.getId());
        reqDTO.setNickName(userGetVO.getNickName());
        reqDTO.setAvatar(userGetVO.getAvatar());
        ContentDetailDomainDTO contentDetailDomainDTO = contentDomainService.detail(reqDTO, contentAgg);

        // 6 关注信息
        List<UserFollowVO> userFollowVOList = myFeignClient.listFollowUser(userContext.getId(), Collections.singletonList(contentDetailDomainDTO.getUserId()));
        if (CollUtil.isNotEmpty(userFollowVOList)) {
            contentDetailDomainDTO.setIsFollowContentUser(YesOrNoEnum.YES.getCode());
        }
        return Convert.convert(ContentDetailAppDTO.class, contentDetailDomainDTO);
    }

    @Override
    public List<ContentListAppDTO> listContent(Long userId, List<Long> contentIds) {
        // 1 获取交互数据
        List<InteractionDataListVO> interactionDataListVOList = myFeignClient.listData(userId, contentIds);

        // 2 作者信息
        List<Content> contentList = contentService.listByIds(contentIds);
        List<Long> userIds = contentList.stream().map(Content::getUserId).collect(Collectors.toList());
        List<UserListVO> userListVOS = myFeignClient.listUser(userIds);

        // 3 获取内容详情
        ContentListReqDTO contentListReqDTO = new ContentListReqDTO();
        contentListReqDTO.setUserId(userId);
        contentListReqDTO.setContentIds(contentIds);
        contentListReqDTO.setContentUsers(Convert.toList(ContentListUserReqDTO.class, userListVOS));
        contentListReqDTO.setInteractions(Convert.toList(ContentListInteractionReqDTO.class, interactionDataListVOList));
        List<ContentListDomainDTO> contentListDomainDTOList = contentDomainService.listContent(contentListReqDTO);

        // 4 获取关注关系
        List<UserFollowVO> userFollowVOList = myFeignClient.listFollowUser(userId, contentListDomainDTOList.stream().map(ContentListDomainDTO::getUserId).collect(Collectors.toList()));
        Map<Long, UserFollowVO> userFollowMap = userFollowVOList.stream().collect(Collectors.toMap(UserFollowVO::getFollowedUserId, e -> e));
        for (ContentListDomainDTO contentListDomainDTO : contentListDomainDTOList) {
            if (Objects.nonNull(userFollowMap.get(contentListDomainDTO.getUserId()))) {
                contentListDomainDTO.setIsFollowContentUser(YesOrNoEnum.YES.getCode());
            }
        }
        return Convert.toList(ContentListAppDTO.class, contentListDomainDTOList);
    }

    @Override
    public PageResult<Long> contentSearch(ContentSearchQry qry) {
        IPage<Content> page = contentService.contentSearch(qry.getKeyword(), qry.getPageNo(), qry.getPageSize());
        if (CollUtil.isEmpty(page.getRecords())) {
            return PageResult.empty(page.getTotal());
        }
        List<Long> contentIds = page.getRecords().stream().map(Content::getId).collect(Collectors.toList());
        return new PageResult<>(contentIds, page.getTotal());
    }

    @Override
    public PageResult<Long> contentQuery(ContentQueryQry qry) {
        IPage<Content> page = contentService.contentQuery(Convert.convert(ContentQueryInfraDTO.class, qry));
        if (CollUtil.isEmpty(page.getRecords())) {
            return PageResult.empty(page.getTotal());
        }
        List<Long> contentIds = page.getRecords().stream().map(Content::getId).collect(Collectors.toList());
        return new PageResult<>(contentIds, page.getTotal());
    }

    @Override
    public PageResult<Long> pageUserPost(UserPostPageQry qry) {
        IPage<Content> page = contentService.pageUserPost(qry.getUserId(), qry.getChannel(), qry.getPageNo(), qry.getPageSize());
        List<Long> contentIds = page.getRecords().stream().map(Content::getId).collect(Collectors.toList());
        return new PageResult<>(contentIds, page.getTotal());
    }
}
